<?php

namespace app\uniapp\service;

use app\common\exception\MiException;
use think\Collection;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\Paginator;
use think\response\Json;
use function jsonSuccess;
use function request;
use function validate;

class UniReqService
{
    private \think\Request $request;

    protected $actionFlag;  // 最后一次操作的标记
    protected $row;
    protected $validate;
    protected Collection|Paginator $list;
    protected UniBaseService $service;

    public static function instance(): static
    {
        return new static();
    }

    public function __construct(){
        $this->request = request();
    }

    public function setService(UniBaseService $service): static
    {
        $this->service = $service;
        return $this;
    }

    public function setValidate($validate){
        $this->validate = $validate;
    }

    /**
     * 排序
     * @param string $order
     * @return $this
     */
    public function setOrder(string $order=''): static
    {
        if (!$order){
            $field = $this->request->param('field', 'create_time');
            $order = $this->request->param('order', 'desc');
            $order = "$field $order";
        }

        $this->service->setOrder($order);

        return $this;
    }

    /**
     * @throws MiException
     */
    public function add($data=null): static
    {
        $this->actionFlag = 'add';
        $req = $this->request;
        if($req->isPost()){
            if (!$data) $data = $this->request->except(['create_time', 'update_time'], 'post');
            // 验证表单数据
            if ($this->validate){
                validate($this->validate)->check($data);
            }

            $this->row = $this->service->create($data);

            return $this;

        }else{
            throw new MiException(REQUEST_ERROR);
        }
    }

    /**
     * @throws MiException
     */
    public function edit($data=null): static
    {
        $this->actionFlag = 'edit';
        if($this->request->isPost()){

            if (!$data) $data = $this->request->except(['create_time', 'update_time'], 'post');
            $idKey = $this->service->pk;
            $id = $data[$idKey]??'';


            if(!$id){
                throw new MiException(NOT_FOUND);
            }
            // 验证表单数据
            if ($this->validate){
                validate($this->validate)->check($data);
            }
            // 更新数据
            $this->row = $this->service->update($data, [$idKey => $id]);
            return $this;
        }

        throw new MiException(REQUEST_ERROR);
    }

    /**
     * 不分页列表查询
     * @throws ModelNotFoundException
     * @throws DbException
     * @throws DataNotFoundException
     */
    public function setSelect(): static
    {
        $this->actionFlag = 'list';
        $this->list = $this->service->select();
        return $this;
    }

    /**
     * @throws DbException
     */
    public function setPaginate(): static
    {
        $this->actionFlag = 'page_list';
        $limit = $this->request->param('limit',20);
        $this->list = $this->service->paginate($limit);
        return $this;
    }



    public function setFind(): static
    {
        $this->actionFlag = 'find';
        $id = $this->request->param($this->service->pk);
        $this->row = $this->service->setPkWhere($id)->find();
        return $this;
    }

    public function getList(): Collection
    {
        return $this->list;
    }

    /**
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     * @throws DbException
     * @throws MiException
     */
    public function delete($ids=null): static
    {
        $this->actionFlag = 'del';
        if (!$ids) $ids = $this->request->param('ids');
        if (!$ids) {
            throw new MiException(NOT_FOUND);
        }
        // 是否彻底删除
        $isForce = $this->request->param('is_force', false);
        $isForce = (bool)$isForce;
        if ($isForce){
            $this->service->setForce(true);
        }
        $this->service->setWhere([[$this->service->pk, 'in', $ids]])->delete();
        return $this;
    }

        /**
     * @return Json|void
     */
    public function getResponse() {
        $flag = $this->actionFlag;
        if ($flag == 'page_list'){
            return jsonSuccess([
                'items' => $this->list->items(),
                'total' => $this->list->total(),
            ]);
        }else if ($flag == 'list'){
            return jsonSuccess([
                'items' => $this->list,
            ]);
        }else if($flag == 'find') {
            return jsonSuccess([
                'info' => $this->row,
            ]);
        }else if($flag == 'add') {
            return jsonSuccess([
                'info' => $this->row,
            ]);
        }else if($flag == 'edit') {
            return jsonSuccess([
                'info' => $this->row,
            ]);
        }else if($flag == 'del') {
            return jsonSuccess();
        }
    }

}
